#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSettings>
#include <QCoreApplication>
#include <QDir>

int judge=0;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    p=new int*[4];
    for(int i=0;i<4;i++){
        *(p+i)=new int[4];
    }
    ui->setupUi(this);

    ui->label->setScaledContents(true);//icon大小适应label

    //读ini信息
    QSettings inidata(QCoreApplication::applicationDirPath()+"/history.ini",QSettings::IniFormat);
    if(inidata.childKeys().count()==0)
        inidata.setValue("highest",0);
    bestScore=inidata.value("highest").toInt();


    setWindowTitle("2048");
    //初始化格子
    for (int i=0;i<4 ;i++ ) {
        for (int j=0;j<4 ;j++ ) {
            c[i][j]=0;
        }
    }
    ui->Easy->setText("Easy Mode");
    ui->Easy->setGeometry(550,240,200,50);
    ui->Difficult->setText("Difficult Mode");
    ui->Difficult->setGeometry(550,300,200,50);
    ui->rule->setText("Rule");
    ui->rule->setGeometry(550,360,200,50);
    ui->quit->setText("Quit");
    ui->quit->setGeometry(550,420,200,50);


    //随机种子
    qsrand(uint(QTime(0,0,0).secsTo(QTime::currentTime())));
}

MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::paintEvent(QPaintEvent *)
{
    //设置画笔
    QPainter p(this);
    p.setBrush(Qt::blue);
    p.setFont(QFont("微软雅黑",20,700,false));

    //画背景
    QRect r = rect();
    QImage img(":/background.jpg");
    p.drawImage(r,img);

    QString strscore;
    p.drawText(QPoint(20,60),"Score:"+QString::number(score));
    p.drawText(QPoint(20,550),"BestScore:"+QString::number(bestScore));

    //画格子
    for (int i=0;i<4 ;i++ ) {
        for (int j=0;j<4 ;j++ ) {
            p.setPen(Qt::transparent);
            if(c[i][j]==0){
                p.setBrush(Qt::gray);
                p.drawRect(i*90+100,j*90+120,80,80);
            }
            else if(c[i][j]==2){
                p.setBrush(Qt::yellow);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(2),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==4){
                p.setBrush(Qt::darkYellow);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(4),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==8){
                p.setBrush(Qt::red);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(8),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==16){
                p.setBrush(Qt::red);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(16),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==32){
                p.setBrush(Qt::darkRed);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(32),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==64){
                p.setBrush(Qt::green);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(64),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==128){
                p.setBrush(Qt::cyan);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(128),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==256){
                p.setBrush(Qt::darkCyan);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(256),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==512){
                p.setBrush(Qt::blue);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(512),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==1024){
                p.setBrush(Qt::darkBlue);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(1024),QTextOption(Qt::AlignCenter));
            }
            else if(c[i][j]==2048){
                p.setBrush(Qt::white);
                p.drawRect(i*90+100,j*90+120,80,80);
                p.setPen(Qt::black);
                p.setFont(QFont("微软雅黑",10,700,false));
                p.drawText(QRectF(i*90+100,j*90+120,80,80),QString::number(2048),QTextOption(Qt::AlignCenter));

            }
        }
    }
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(!state){
        return;
    }
    for (int i=0;i<4;i++ ) {
        for (int j=1;j<4 ;j++ ) {
            p[i][j]=c[i][j];
        }
    }
    switch (event->key()) {
    case Qt::Key_W:
        Up();
        break;
    case Qt::Key_S:
        Down();
        break;
    case Qt::Key_A:
        Left();
        break;
    case Qt::Key_D:
        Right();
        break;
    default:
        return;
    }

    if(score>bestScore)
    {
        bestScore=score;
        QSettings inidata(QCoreApplication::applicationDirPath()+"/history.ini",QSettings::IniFormat);
        inidata.setValue("highest",bestScore);
    }
    if(judge==1){
    int moveable=1;
    for (int i=0;i<4;i++ ) {
        for (int j=1;j<4 ;j++ ) {
            if(p[i][j]!=c[i][j])
                moveable=0;
        }
    }
        if(moveable==0){
           myRand();//随机按钮
        }
    }
    else
        myRand();
    judgeStatus();
    update();
}
void MainWindow::Up()
{
    for (int i=0;i<4;i++ ) {
        for (int j=1;j<4 ;j++ ) {
            p[i][j]=c[i][j];
        }
    }
    for (int i=0;i<4;i++ ) {
        for (int j=1;j<4 ;j++ ) {
            if(c[i][j]==0)continue;
            for(int p=0;p<j;p++){
                //查找上方是否有空格子
                if(c[i][p]==0){
                    c[i][p]=c[i][j];
                    c[i][j]=0;
                    break;
                }
            }
        }
    }
    //加和
    for(int i=0;i<4;i++){
        for(int j=0;j<3;j++){
            if(c[i][j]==c[i][j+1]){
                c[i][j]=c[i][j]+c[i][j+1];
                c[i][j+1]=0;
                score+=c[i][j];
            }
        }
    }
    //移动方格
    for(int i=0;i<4;i++){
        for(int j=1;j<3;j++){
            if(c[i][j]==0){
                int t=j+1;
                    if(c[i][t]!=0){
                        int tmp;
                        tmp=c[i][t];
                        c[i][t]=c[i][j];
                        c[i][j]=tmp;
                   }
                }
            }
        }

}

void MainWindow::Down()
{
    for (int i=0;i<4;i++ ) {
        for (int j=2;j>=0 ;j-- ) {
            if(c[i][j]==0)continue;
            for(int p=3;p>j;p--){
                //查找下方是否有空格子
                if(c[i][p]==0){
                    c[i][p]=c[i][j];
                    c[i][j]=0;
                    break;
                }
            }
        }
    }
    //加和
    for(int i=0;i<4;i++){
        for(int j=3;j>0;j--){
            if(c[i][j]==c[i][j-1]){
                c[i][j]=2*c[i][j];
                c[i][j-1]=0;
                score+=c[i][j];
            }
        }
    }
    //移动方格
    for(int i=0;i<4;i++){
        for(int j=2;j>0;j--){
            if(c[i][j]==0){
                int t=j-1;
                    if(c[i][t]!=0){
                        int tmp;
                        tmp=c[i][t];
                        c[i][t]=c[i][j];
                        c[i][j]=tmp;
                   }
                }
            }
        }

}

void MainWindow::Right()
{
    for (int j=0;j<4;j++ ) {
        for (int i=2;i>=0;i-- ) {
            if(c[i][j]==0)continue;
            for(int p=3;p>i;p--){
                //查找右方是否有空格子
                if(c[p][j]==0){
                    c[p][j]=c[i][j];
                    c[i][j]=0;
                    break;
                }
            }
        }
    }
    //加和
    for (int j=0;j<4;j++ ) {
        for (int i=3;i>0;i-- ) {
            if(c[i][j]==c[i-1][j]){
                c[i][j]=2*c[i][j];
                c[i-1][j]=0;
                score+=c[i][j];
            }
        }
    }
    //移动方格
    for(int j=0;j<4;j++){
        for(int i=2;i>0;i--){
            if(c[i][j]==0){
                int t=i-1;
                    if(c[t][j]!=0){
                        int tmp;
                        tmp=c[t][j];
                        c[t][j]=c[i][j];
                        c[i][j]=tmp;
                   }
                }
            }
        }
}

void MainWindow::Left()
{
    for (int j=0;j<4;j++) {
        for (int i=1;i<4;i++) {
            if(c[i][j]==0)continue;
            for (int p=0;p<i;p++) {
                //查看前面是否有空格可移入
                if(c[p][j] == 0){
                    c[p][j] = c[i][j];
                    c[i][j] = 0;
                    break;
                }
            }
        }
    }
    //相加
    for (int j=0;j<4;j++) {
        for (int i=0;i<3;i++) {
            if(c[i][j]==c[i+1][j]){
                c[i][j]=c[i][j]*2;
                score+=c[i][j];
                c[i+1][j]=0;
            }
        }
    }
    //移动方格
    for(int j=0;j<4;j++){
        for(int i=1;i<3;i++){
            if(c[i][j]==0){
                int t=i+1;
                    if(c[t][j]!=0){
                        int tmp;
                        tmp=c[t][j];
                        c[t][j]=c[i][j];
                        c[i][j]=tmp;
                   }
            }
        }
    }
}

void MainWindow::myRand()
{
    //找出空格子
     int i=0,j=0;
     struct Ns{
         int i;
         int j;
     };
     struct Ns n[16];
     int ni=0;
     for(i=0;i<4;i++){
         for(j=0;j<4;j++){
             if(c[i][j]==0){
                 n[ni].i=i;
                 n[ni].j=j;
                 ni++;
             }
         }
     }
     //判断游戏是否结束
     if(ni==0){
         for(i=0;i<4;i++){
             for(j=0;j<3;j++){
                 if(c[i][j]==c[i][j+1]){
                     return;
                 }
             }
         }
         for(j=0;j<4;j++){
             for(i=0;i<3;i++){
                 if(c[i][j]==c[i+1][j]){
                     return;
                 }
             }
         }

     }
     int rand=qrand()%ni;
     c[n[rand].i][n[rand].j]=2;
}

void MainWindow::judgeStatus()
{
    //找出空格子
     int i=0,j=0;
     struct Ns{
         int i;
         int j;
     };
     struct Ns n[16];
     int ni=0;
     for(i=0;i<4;i++){
         for(j=0;j<4;j++){
             if(c[i][j]==0){
                 n[ni].i=i;
                 n[ni].j=j;
                 ni++;
             }
         }
     }
     //判断游戏是否结束
     if(ni==0){
         for(i=0;i<4;i++){
             for(j=0;j<3;j++){
                 if(c[i][j]==c[i][j+1]){
                     return;
                 }
             }
         }
         for(j=0;j<4;j++){
             for(i=0;i<3;i++){
                 if(c[i][j]==c[i+1][j]){
                     return;
                 }
             }
         }
         QMessageBox::about(this,"Game Over!","Your score is:"+QString::number(score));
                 return;

     }
}


void MainWindow::on_rule_clicked()
{
    rule *g=new rule(this);
    g->show();
}

void MainWindow::on_quit_clicked()
{
    this->close();
}

void MainWindow::slotstart()
{
    score=0;
    for (int i=0;i<4 ;i++ ) {
        for (int j=0;j<4 ;j++ ) {
            c[i][j]=0;
        }
    }
    int randi=qrand()%4;
    int randj=qrand()%4;
    c[randi][randj]=2;
    state=true;
    update();
}

void MainWindow::on_Easy_clicked()
{
    slotstart();
    judge=0;
}


void MainWindow::on_Difficult_clicked()
{
    slotstart();
    judge=1;
}
